package cloud.seckill.ribbonserver.config.loadbalancer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @title: MyLB
 * @Author Wangsj
 * @Date: 2021/5/25
 */
@Slf4j
@Component
public class MyLB implements LoadBalancer{

    /**记录当前接口请求的次数*/
    private AtomicInteger atomicInteger=new AtomicInteger(0);

    /**
     * 1、获取当前接口请求次数
     * 2、使用 CAS(比较和替换) 自选锁的方式 ,判断当前值(this.atomicInteger.get())与期望值（current）
     * 是否一致。
     *      若一致：代表当前没有其他用户请求该接口，可以修改 请求接口次数的值 atomicInteger + 1。
     *      若不一致：存在其他用户操作该值，自旋等待直到当前值与期望值一致。
     * @return 修改后的请求接口次数
     */
    private final int getAndIncrement(){
        int current;
        int next;
        do{
            current=this.atomicInteger.get();
            next = current >= Integer.MAX_VALUE ? 0 : current+1;
        }while (!this.atomicInteger.compareAndSet(current,next));
        log.info("--------------- 第{}次购买",next);
        return next;
    }

    public void initAtomic(){
        this.atomicInteger=new AtomicInteger(0);
        log.info("-------------------init loadbalancer success！！！");
    }


    /**
     * 实际调用服务器位置下标 = rest 接口第几次请求数 % 服务器集群总数量
     * @param serviceInstances
     * @return 下次服务请求的端口号
     */
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}
